package com.hyt.it.ogt.kq.service.bm.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.hyt.core.base.BaseEntity;
import com.hyt.core.base.BaseServiceImpl;
import com.hyt.exception.exception.InvalidRequestException;
import com.hyt.it.ogt.kq.common.config.ConfigManager;
import com.hyt.it.ogt.kq.common.config.exception.KqException;
import com.hyt.it.ogt.kq.common.gov.constant.ResponseCode;
import com.hyt.it.ogt.kq.common.gov.utils.CacheKeyManager;
import com.hyt.it.ogt.kq.service.bm.mapper.ProjectExamMapper;
import com.hyt.it.ogt.kq.service.bm.model.entity.ProjectExam;
import com.hyt.it.ogt.kq.service.bm.service.IProjectExamService;
import com.hyt.it.ogt.kq.service.govData.service.bm.IProjectStudentService;
import com.hyt.it.ogt.kq.service.govData.service.kwgov.IKwBingService;
import com.hyt.it.ogt.kq.service.model.vo.candidateSubject.BmTaskData;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

import static com.hyt.it.ogt.kq.common.gov.enums.CacheKeyEnum.*;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author liteng
 * @since 2021-08-10
 */
@Slf4j
@Service
public class ProjectExamServiceImpl extends BaseServiceImpl<ProjectExamMapper, ProjectExam> implements IProjectExamService {

    @Autowired
    private ConfigManager configManager;
    @Resource
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private IKwBingService iKwBingService;
    @Resource
    private IProjectStudentService iProjectStudentService;

    public static final int DEFAULT_TOTAL = 100;


    @Transactional(rollbackFor = Exception.class)
    @Override
    public BmTaskData bindProjectExam(String userId, String taskId, String projectId) throws Exception {
        // 删除错误信息
        String lockErrKey = GOV_BING_BM_ERROR_CACHE_KEY.getCacheEnumKey(taskId); //CacheKeyManager.getKwBingingDataLockErrKey(taskId);
        redisTemplate.delete(lockErrKey);

        String progressKey = GOV_BING_BM_PROCESS_CACHE_KEY.getCacheEnumKey(taskId); //CacheKeyManager.getBingingLockProgressKey(taskId);
        redisTemplate.delete(progressKey);

        String totalProgressKey = GOV_BING_BM_TOTAL_CACHE_KEY.getCacheEnumKey(taskId); //CacheKeyManager.getKwBingingDataLockTotalKey(taskId);
        redisTemplate.opsForValue().set(totalProgressKey, DEFAULT_TOTAL);

        return syncData(userId, taskId, projectId);
    }

    @Override
    public void checkHasBindKwGov(String projectId) {
        List<ProjectExam> projectExams = this.lambdaQuery()
                .eq(ProjectExam::getProjectId, projectId)
                .eq(BaseEntity::getDelFlag, Boolean.FALSE)
                .list();
        if (CollUtil.isNotEmpty(projectExams)) {
            InvalidRequestException.throwException(31242503, "当前报名任务已绑定考务", projectId);
        }
    }

    @Override
    public ProjectExam getProjectExamByProjectId(String projectId) {
        ProjectExam projectExam = this.lambdaQuery()
                .eq(ProjectExam::getProjectId, projectId)
                .eq(BaseEntity::getDelFlag, Boolean.FALSE)
                .last("limit 1").one();
        if (null != projectExam) {
            return projectExam;
        }
        return null;
    }

    @SneakyThrows
    private BmTaskData syncData(String userId, String taskId, String projectId) {
        String creatingKey = GOV_BING_BM_LOCK_KEY.getCacheEnumKey(taskId); //CacheKeyManager.getKwBingDataLockKey(taskId);
        String progressKey = GOV_BING_BM_PROCESS_CACHE_KEY.getCacheEnumKey(taskId);    //CacheKeyManager.getBingingLockProgressKey(taskId);
        // 删除错误信息
        String lockErrKey = GOV_BING_BM_ERROR_CACHE_KEY.getCacheEnumKey(taskId); //CacheKeyManager.getKwBingingDataLockErrKey(taskId);
        // 开始同步数据
        try {
            // 校验考务绑定条件
            iKwBingService.verifyBingCondition(projectId, taskId);

            redisTemplate.opsForValue().set(progressKey, 10);
            // 获取所有的报名数据
            BmTaskData bmTaskData = iProjectStudentService.getBmTaskDataByProjectIdAndTaskId(userId, taskId, projectId, progressKey);

            redisTemplate.opsForValue().set(progressKey, 30);

            // 绑定报名数据同步考务库
            iKwBingService.bindBm(taskId, projectId, bmTaskData);
            redisTemplate.opsForValue().set(progressKey, 100);
            return bmTaskData;
        } catch (KqException kqException) {
            redisTemplate.opsForValue().set(lockErrKey, kqException.getErrCode());
            log.error("## syncData error", kqException);
            throw kqException;
        } catch (Exception e) {
            redisTemplate.opsForValue().set(lockErrKey, ResponseCode.ERROR_OVERVIEW_BIND.getCode());
            log.error("## syncData error", e);
            throw e;
        } finally {
            log.info("## syncData 开始释放锁：{}, {}", creatingKey, taskId);
            String lockKey = CacheKeyManager.getKwBingDataLockKey(taskId);
            redisTemplate.delete(lockKey);
        }
    }
}
